#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>

#define LED 2

auto ssid = "tp_lwb";
auto password = "12345678";

// MQTT 配置
auto mqtt_server = "180.107.109.102";
constexpr int mqtt_port = 1883;
auto mqtt_user = "admin";
auto mqtt_password = "nttieren0513";
unsigned long lastReconnectAttempt = 0;

WiFiClient espClient;
PubSubClient client(espClient);

// 接收消息回调函数
void callback(const char* topic, const u_int8_t* payload, const unsigned int length)
{
    // 参数验证
    if (topic == nullptr || payload == nullptr)
    {
        return;
    }

    // 验证长度合理性（防止缓冲区溢出）
    if (length == 0)
    {
        Serial.println();
        return;
    }

    digitalWrite(LED, LOW);
    // 打印接收到的消息
    for (int i = 0; i < length; i++)
    {
        Serial.print(static_cast<char>(payload[i]));
    }
    Serial.println();
    delay(50);
    digitalWrite(LED, HIGH);
}

boolean reconnect()
{
    if (client.connect("esp32_001", mqtt_user, mqtt_password))
    {
        client.subscribe("esp32/commands", 1);
    }
    return client.connected();
}

void initSta()
{
    Serial.println("******************************************************");
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFiClass::status() != WL_CONNECTED)
    {
        delay(100);
        digitalWrite(LED, HIGH);
        delay(100);
        digitalWrite(LED, LOW);
        Serial.print(".");
    }

    Serial.println("\nWiFi connected");
    Serial.print("IP / MAC: ");
    Serial.print(WiFi.localIP());
    Serial.print(" / ");
    Serial.println(WiFi.macAddress());
    digitalWrite(LED, HIGH);
}

void initMqtt()
{
    // 设置 MQTT
    client.setServer(mqtt_server, mqtt_port);
    client.setCallback(callback);
}

void setup()
{
    pinMode(LED, OUTPUT);
    Serial.begin(9600);

    initSta();
    initMqtt();
}

void loop()
{
    if (!client.loop())
    {
        unsigned long now = millis();
        if (now - lastReconnectAttempt > 5000)
        {
            lastReconnectAttempt = now;
            // Attempt to reconnect
            if (reconnect())
            {
                Serial.println("MQTT connected");
                lastReconnectAttempt = 0;
            }
        }
    }
}
